'*******************************************************************************
' *  
' *  Product: GSALib
' *  Description: A C# API for accessing the Google Search Appliance.
' *
' *  (c) Copyright 2008 Michael Cizmar + Associates Ltd.  (MC+A)
' *  
'*******************************************************************************


Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Text
Imports GSALibVB.GSALib.Utils

Namespace GSALib.GSA
    ''' <summary>
    ''' Class for creating query string for submitting http requests to GSA
    ''' <para>Author Albert Ghukasyan</para>
    ''' </summary>
    Friend NotInheritable Class QueryBuilder
#Region "Variables"

        Private as_dt As Char
        ' {i, e}:{include [as_sitesearch], exclude [as_sitesearch]}
        Private as_epq As String
        ' additional query terms
        Private as_eq As String
        ' exclude terms
        Private as_lq As String
        ' pages linking to this url
        Private as_occt As String
        ' {any, title, URL}:{search anywhere on page, search in title, search in url}
        Private as_oq As String()
        ' any of these
        Private as_q As String()

        Private q As String
        ' *REQUIRED when sitesearch specified* Search query
        Private as_sitesearch As String
        ' *MAX 118 after URL encoding* set the value for this into "site"
        Private sitesearch As String
        ' needs q to be supplied
        Private sites As String()
        ' *REQUIRED* (OR-ed) collection of "collections" ()
        Private client As String
        ' *REQUIRED* string specifying valid frontend      (default -needs to be speficied- is default_frontend)
        Private output As String
        ' *REQUIRED* format for search results      (default -needs to be specified- is xml_no_dtd)
        Private proxycustom As String
        ' {<HOME/>,<ADVANCED/>,<TEST/>}
        Private proxyreload As Boolean
        ' {1} force reload of serverside stylesheet (else default reloaded after 15 mins)
        Private proxystylesheet As String
        ' if output==xml_no_dtd then {Omitted,}
        Private access As Char
        ' {p, s, a}:{public, secure, all}
        Private filter As Char
        ' 0,1,p,s  (default is 1)
        Private lr As String
        ' Language restrict
        Private ie As String
        ' Input encoding      (default is latin1)
        Private oe As String
        ' Output encoding     (default is UTF8)
        Private start As Long
        ' {0..999} scroll into the search results (constraint: start+num <= 1000)
        Private num As Integer
        ' {1..100} max results per request     (default is 10)
        Private numgm As Byte
        ' {0..5} max num of keymatches per result     (default is 3)
        Private getfields As String()
        ' get meta tags
        Private partialfields As Hashtable
        ' meta tag names and partial-values
        Private partialFieldsOr As Boolean = True
        ' used in conjunction with partialFields
        Private requiredfields As Hashtable
        ' meta tag names and complete-values
        Private requiredFieldsOr As Boolean = True
        ' used in conjunction with requiredFields
        Private sort As String
        ' Only date is currently supported
        Private AS_DT_INCLUDE As Char = "i"c
        Private AS_DT_EXCLUDE As Char = "e"c
        Private FILTER_DUP_SNIPPET_AND_DIRECTORY As Char = "1"c
        Private FILTER_OFF As Char = "0"c
        Private FILTER_DUP_SNIPPET As Char = "p"c
        Private FILTER_DUP_DIRECTORY As Char = "s"c
        Private _DEFAULT_ACCESS As Char = "p"c
        Private _DEFAULT_OUTPUT As String = "xml_no_dtd"

#End Region

#Region "Constructor"

        Friend Sub New(ByVal query As String, ByVal output As String)
            Me.q = query
            Me.output = IIf(output Is Nothing, _DEFAULT_OUTPUT, output)
            Me.access = _DEFAULT_ACCESS
            Me.requiredfields = New Hashtable()
            Me.partialfields = New Hashtable()
        End Sub

#End Region

#Region "Set Properties"

        Public Sub setAccess(ByVal access As Char)
            Me.access = access
        End Sub

        Public Function getAccess() As Char
            Return Me.access
        End Function

        Public Sub setAs_dt(ByVal as_dt As Char)
            Me.as_dt = as_dt
        End Sub

        Public Sub setAs_epq(ByVal as_epq As String)
            Me.as_epq = as_epq
        End Sub

        Public Sub setAs_eq(ByVal as_eq As String)
            Me.as_eq = as_eq
        End Sub

        Public Sub setAs_lq(ByVal as_lq As String)
            Me.as_lq = as_lq
        End Sub

        Public Sub setAs_occt(ByVal as_occt As String)
            Me.as_occt = as_occt
        End Sub

        Public Sub setAs_oq(ByVal as_oq As String())
            Me.as_oq = as_oq
        End Sub

        Public Sub setAs_q(ByVal as_q As String())
            Me.as_q = as_q
        End Sub

        Public Sub setAs_sitesearch(ByVal as_sitesearch As String)
            Me.as_sitesearch = as_sitesearch
        End Sub

        Public Sub setClient(ByVal client As String)
            Me.client = client
        End Sub

        Public Sub setFilter(ByVal filter As Char)
            Me.filter = filter
        End Sub

        Public Sub setGetfields(ByVal getfields As String())
            Me.getfields = getfields
        End Sub

        Public Sub setPartialfields(ByVal partialfields As Hashtable, ByVal orIfTrueAndIfFalse As Boolean)
            Me.partialfields = partialfields
            Me.partialFieldsOr = orIfTrueAndIfFalse
        End Sub

        Public Sub setRequiredfields(ByVal requiredfields As Hashtable, ByVal orIfTrueAndIfFalse As Boolean)
            Me.requiredfields = requiredfields
            Me.requiredFieldsOr = orIfTrueAndIfFalse
        End Sub

        Public Sub setIe(ByVal ie As String)
            Me.ie = ie
        End Sub

        Public Sub setLr(ByVal lr As String)
            Me.lr = lr
        End Sub

        Public Sub setNum(ByVal num As Integer)
            Me.num = num
        End Sub

        Public Sub setNumgm(ByVal numgm As Byte)
            Me.numgm = numgm
        End Sub

        Public Sub setOe(ByVal oe As String)
            Me.oe = oe
        End Sub

        Public Sub setOutput(ByVal output As String)
            Me.output = output
        End Sub

        Public Sub setProxycustom(ByVal proxycustom As String)
            Me.proxycustom = proxycustom
        End Sub

        Public Sub setProxyreload(ByVal proxyreload As Boolean)
            Me.proxyreload = proxyreload
        End Sub

        Public Sub setProxystylesheet(ByVal proxystylesheet As String)
            Me.proxystylesheet = proxystylesheet
        End Sub

        Public Sub setQ(ByVal q As String)
            Me.q = q
        End Sub

        Public Sub setSites(ByVal sites As String())
            Me.sites = sites
        End Sub

        Public Sub setSitesearch(ByVal sitesearch As String)
            Me.sitesearch = sitesearch
        End Sub

        Public Sub setSort(ByVal sort As String)
            Me.sort = sort
        End Sub

        Public Sub setStart(ByVal start As Long)
            Me.start = start
        End Sub

#End Region

#Region "GetValue"

        ''' <summary>
        ''' Builds Query via appending string to  String builder ( refer to Util.appendQueryParam)
        ''' </summary>
        ''' <returns>Builded Query String</returns>
        Public Function getValue() As String
            Dim sbuf As New StringBuilder()
            Util.appendQueryParam(sbuf, "access", access.ToString())
            If output IsNot Nothing Then
                Util.appendQueryParam(sbuf, "output", output)
            End If
            If sort IsNot Nothing Then
                Util.appendQueryParam(sbuf, "sort", sort)
            End If
            If ie IsNot Nothing Then
                Util.appendQueryParam(sbuf, "ie", ie)
            End If
            If oe IsNot Nothing Then
                Util.appendQueryParam(sbuf, "oe", oe)
            End If
            Util.appendQueryParam(sbuf, "client", client)
            If start > 0 Then
                Util.appendQueryParam(sbuf, "start", start.ToString())
            End If
            If q IsNot Nothing Then
                Util.appendQueryParam(sbuf, "q", q)
            End If
            If as_dt = AS_DT_INCLUDE OrElse as_dt = AS_DT_EXCLUDE Then
                Util.appendQueryParam(sbuf, "as_dt", as_dt.ToString())
            End If
            If as_epq IsNot Nothing Then
                Util.appendQueryParam(sbuf, "as_epq", as_epq)
            End If
            If as_eq IsNot Nothing Then
                Util.appendQueryParam(sbuf, "as_eq", as_eq)
            End If
            If as_lq IsNot Nothing Then
                Util.appendQueryParam(sbuf, "as_lq", as_lq)
            End If
            If as_occt IsNot Nothing Then
                Util.appendQueryParam(sbuf, "as_occt", as_occt)
            End If
            If as_oq IsNot Nothing Then
                Dim temp As String = Util.SeparatedString(as_oq, Nothing, " ")
                Util.appendQueryParam(sbuf, "as_oq", temp)
            End If
            If as_q IsNot Nothing Then
                Dim temp As String = Util.SeparatedString(as_q, Nothing, " ")
                Util.appendQueryParam(sbuf, "as_q", temp)
            End If

            If as_sitesearch IsNot Nothing Then
                Util.appendQueryParam(sbuf, "as_sitesearch", as_sitesearch)
            End If
            If filter = FILTER_DUP_DIRECTORY OrElse filter = FILTER_DUP_SNIPPET OrElse filter = FILTER_DUP_SNIPPET_AND_DIRECTORY OrElse filter = FILTER_OFF Then
                Util.appendQueryParam(sbuf, "filter", filter.ToString())
            End If
            If lr IsNot Nothing Then
                Util.appendQueryParam(sbuf, "lr", lr)
            End If
            If num > 0 Then
                Util.appendQueryParam(sbuf, "num", num.ToString())
            End If
            If numgm > 0 Then
                Util.appendQueryParam(sbuf, "numgm", numgm.ToString())
            End If
            If proxycustom IsNot Nothing Then
                Util.appendQueryParam(sbuf, "proxycustom", proxycustom)
            End If
            If proxyreload Then
                Util.appendQueryParam(sbuf, "proxyreload", "1")
            End If
            If proxystylesheet IsNot Nothing Then
                Util.appendQueryParam(sbuf, "proxystylesheet", proxystylesheet)
            End If
            If sitesearch IsNot Nothing Then
                Util.appendQueryParam(sbuf, "sitesearch", sitesearch)
            End If
            If requiredfields IsNot Nothing AndAlso requiredfields.Count > 0 Then
                Util.appendMappedQueryParams(sbuf, "requiredfields", requiredfields, IIf(requiredFieldsOr, "|", "."))
            End If
            If partialfields IsNot Nothing AndAlso partialfields.Count > 0 Then
                Util.appendMappedQueryParams(sbuf, "partialfields", partialfields, IIf(partialFieldsOr, "|", "."))
            End If
            If getfields IsNot Nothing AndAlso getfields.Length > 0 Then
                Dim allFields As String = Util.SeparatedString(getfields, "", ".")
                Util.appendQueryParam(sbuf, "getfields", allFields)
            End If
            If sites IsNot Nothing AndAlso sites.Length > 0 Then
                Dim allSites As String = Util.SeparatedString(sites, "", "|")
                Util.appendQueryParam(sbuf, "site", allSites)
            End If
            Return sbuf.ToString()
        End Function

#End Region
    End Class
End Namespace
